#ifndef TINX_FB_H
#define TINX_FB_H

#include <tinx/types.h>

#define FBIOGET_VSCREENINFO     0x4600
#define FBIOPUT_VSCREENINFO     0x4601
#define FBIOGET_FSCREENINFO     0x4602

// 越往下优先级越高
enum
{
    FB_TYPE_NULL,
    FB_TYPE_VESA,
    FB_TYPE_NUM
};

typedef struct fb_op_t
{
    int (*set_mode) (int width, int height, int bpp);
    int (*reset) (void);
    u32 (*get_framebuffer) (void);
} fb_op_t;

typedef struct framebuffer_t
{
    u32 fb_vaddr;
    u32 fb_paddr;
    u32 fb_len;

    u32 width;
    u32 height;
    u32 bpp;

    int type;
    fb_op_t *op;
} framebuffer_t;

typedef struct fb_bitfield_t
{
    u32 offset;           // 字段在像素中的偏移
    u32 length;           // 字段长度 (位数)
    u32 msb_right;        // 如果为1，表示MSB在右边
} fb_bitfield_t;

typedef struct fb_var_screeninfo_t
{
    u32 xres;            // 可见水平分辨率
    u32 yres;            // 可见垂直分辨率
    u32 xres_virtual;    // 虚拟水平分辨率
    u32 yres_virtual;    // 虚拟垂直分辨率
    u32 bits_per_pixel;  // 每像素位数 (颜色深度)
    
    // 颜色格式
    fb_bitfield_t red;
    fb_bitfield_t green;
    fb_bitfield_t blue;
    fb_bitfield_t transp;
    
    // 时序参数
    u32 pixclock;        // 像素时钟 (皮秒)
    u32 left_margin;     // 水平回扫时间
    u32 right_margin;
    u32 upper_margin;    // 垂直回扫时间
    u32 lower_margin;
    u32 hsync_len;       // 水平同步脉冲宽度
    u32 vsync_len;       // 垂直同步脉冲宽度
    u32 sync;            // 同步极性标志
    u32 vmode;           // 视频模式标志
    u32 rotate;          // 显示旋转角度
    u32 colorspace;      // 颜色空间

    // 保留字段
    u32 reserved[4];
} fb_var_screeninfo_t;

typedef struct fb_fix_screeninfo_t
{
    char id[16];            // 设备标识字符串
    u32 smem_start; // 显存起始地址 (物理地址)
    u32 smem_len;         // 显存总长度 (字节)
    u32 type;             // 帧缓冲类型
    u32 type_aux;         // 辅助类型信息
    u32 visual;           // 视觉类型
    u16 xpanstep;         // 水平平移步长
    u16 ypanstep;         // 垂直平移步长
    u16 ywrapstep;        // ywrap 步长
    u32 line_length;      // 每行字节数

    // 内存映射IO地址
    u32 mmio_start;
    u32 mmio_len;         // 内存映射IO长度

    u32 accel;            // 加速类型标志

    // 保留字段
    u16 reserved[3];
} fb_fix_screeninfo_t;

fb_op_t *fb_get_op(int type);
void fb_register_op(int type, fb_op_t *op);

#endif